package modbus_client

import (
	"backend/internal/core/types"
	"backend/internal/db/model"
	"github.com/zeromicro/go-zero/core/logx"
	"sync"
)

// ClientManager 管理 Modbus 客户端的结构体
type ClientManager struct {
	clientMap map[string]*ModbusClient
	mu        sync.RWMutex
}

// NewClientManager 创建一个新的 ClientManager 实例
func NewClientManager() *ClientManager {
	return &ClientManager{
		clientMap: make(map[string]*ModbusClient),
	}
}

// SetAllClient 从数据库获取设备列表并创建对应的 Modbus 客户端
func (cm *ClientManager) SetAllClient(deviceList []model.Device) {
	for _, device := range deviceList {
		deviceName := device.Name
		ip := device.IP
		port := device.Port
		protocol := device.Protocol

		switch protocol {
		case types.Tcp:
			cm.AddModbusTCPClient(deviceName, ip, port)
		case types.RtuOverTcp:
			cm.AddModbusRtuOverTcpClient(deviceName, ip, port)
		case types.Rtu:
			cm.AddModbusRtuClient(deviceName, "COM1", 9600, "N", 1, 8, 1000)
			// 可添加其他协议类型
		default:
			logx.Errorf("不支持的协议类型: %v", protocol)
		}
	}
}

// ClearAllClients 清理 clientMap 里的所有 Modbus 客户端
func (cm *ClientManager) ClearAllClients() {
	cm.mu.Lock()
	defer cm.mu.Unlock()

	for deviceName, client := range cm.clientMap {
		client.Disconnect()
		delete(cm.clientMap, deviceName)
		logx.Infof("删除客户端: %s", deviceName)
	}
}

// AddModbusTCPClient 添加一个 Modbus Tcp 客户端
func (cm *ClientManager) AddModbusTCPClient(deviceName, ip string, port int32) {
	cm.mu.Lock()
	defer cm.mu.Unlock()

	if _, exists := cm.clientMap[deviceName]; !exists {
		tcpConfig := &types.TcpConfig{
			Host:         ip,
			Port:         port,
			ProtocolType: types.Tcp,
		}
		client := NewModbusClient(types.Tcp, tcpConfig, nil)
		cm.clientMap[deviceName] = client
	}
}

// AddModbusRtuOverTcpClient 添加一个 Modbus Rtu over Tcp 客户端
func (cm *ClientManager) AddModbusRtuOverTcpClient(deviceName, ip string, port int32) {
	cm.mu.Lock()
	defer cm.mu.Unlock()

	if _, exists := cm.clientMap[deviceName]; !exists {
		tcpConfig := &types.TcpConfig{
			Host:         ip,
			Port:         port,
			ProtocolType: types.RtuOverTcp,
		}
		client := NewModbusClient(types.RtuOverTcp, tcpConfig, nil)
		cm.clientMap[deviceName] = client
	}
}

// AddModbusRtuClient 添加一个 Modbus Rtu 客户端
func (cm *ClientManager) AddModbusRtuClient(deviceName, port string, baudrate int32, parity string, stopbits, bytesize int32, timeout int32) {
	cm.mu.Lock()
	defer cm.mu.Unlock()

	if _, exists := cm.clientMap[deviceName]; !exists {
		rtuConfig := &types.RtuConfig{
			Port:     port,
			Baudrate: baudrate,
			Parity:   parity,
			Stopbits: stopbits,
			Bytesize: bytesize,
			Timeout:  timeout,
		}
		client := NewModbusClient(types.Rtu, nil, rtuConfig)
		cm.clientMap[deviceName] = client
	}
}

// EditClient 编辑现有的 Modbus 客户端
func (cm *ClientManager) EditClient(oldDeviceName string, protocolType types.ProtocolType, deviceName, ip string, port int32) error {
	if err := cm.DeleteClient(oldDeviceName); err != nil {
		logx.Errorf("编辑客户端失败: 删除旧客户端 %s 时出错: %v", oldDeviceName, err)
		return err
	}

	switch protocolType {
	case types.Tcp:
		cm.AddModbusTCPClient(deviceName, ip, port)
	case types.RtuOverTcp:
		cm.AddModbusRtuOverTcpClient(deviceName, ip, port)
	// 可添加其他协议类型
	case types.Rtu:
		cm.AddModbusRtuClient(deviceName, "COM1", 9600, "N", 1, 8, 1000)
	default:
		logx.Errorf("不支持的协议类型: %v", protocolType)
	}
	return nil
}

// DeleteClient 删除指定的 Modbus 客户端
func (cm *ClientManager) DeleteClient(deviceName string) error {
	if client, exists := cm.clientMap[deviceName]; exists {
		client.Disconnect()
		delete(cm.clientMap, deviceName)
		logx.Infof("删除客户端: %s", deviceName)
		return nil
	}
	return nil
}

// GetClient 获取指定名称的 Modbus 客户端
func (cm *ClientManager) GetClient(deviceName string) *ModbusClient {
	cm.mu.RLock()
	defer cm.mu.RUnlock()

	if client, exists := cm.clientMap[deviceName]; exists {
		return client
	}
	return nil
}
